using System;
using System.Data;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq;
using Magiq.Support;

namespace Magiq.Sql {
  public abstract class QueryExecutor {
    protected const string TypeReferenceName = "__TypeReference__";
    private readonly bool addTypeReference;

    protected QueryExecutor(DataContext dataContext, IQueryable where, bool addTypeReference) {
      this.addTypeReference = addTypeReference;
      DataContext = dataContext;
      Where = where;
    }

    protected MetaDataMember TypeReferenceMember { get; private set; }
    protected IQueryable Where { get; private set; }
    protected DataContext DataContext { get; private set; }
    protected IDbCommand Command { get; private set; }
    protected TableMapping Mapping { get; private set; }
    public string BaseTableName { get; private set; }

    public string BaseWhereClause {
      get { return Command.CommandText.From("\r\nFROM "); }
    }


    protected void SetCommand(IDbCommand command) {
      Command = command;
      BaseTableName = addTypeReference
                        ? Command.CommandText.From("SELECT").Until(".").Trim()
                        : Mapping.TableName;
    }

    public int ExecuteNonQuery(string sql) {
      Command.CommandText = sql;
      return Command.ExecuteNonQuery();
    }

    protected virtual void Init(Type elementType) {
      Mapping = new TableMapping(elementType, DataContext);
      TypeReferenceMember = Mapping.IdentityMembers.First();
    }
  }
}